package cn.wj.school.cloud.controller;

import cn.wj.school.cloud.dto.DWZResult;
import cn.wj.school.cloud.enums.DwzCallbackType;
import cn.wj.school.cloud.enums.DwzStatusCode;
import cn.wj.school.cloud.exception.ServiceInvokeException;
import cn.wj.school.cloud.utils.AjaxUtil;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class BaseController {

    protected static final Logger LOGGER = LoggerFactory.getLogger(BaseController.class);

    protected static final String NAVTABID = "navTabId";

    /**
     * 300返回dwz客户端的默认message
     */
    public static final String DWZ_CODE_ERROR_MESSAGE = "操作失败，请联系管理员!";
    /**
     * 200返回dwz客户端的默认message
     */
    public static final String DWZ_CODE_OK_MESSAGE = "操作成功";


    @ExceptionHandler
    public String exp(HttpServletRequest request, HttpServletResponse response, Exception ex) {
        String errorMsg;
        // 记录下日志
        LOGGER.error("{}", ex);
        HttpStatus httpStatus = null;
        if (ex instanceof ServiceInvokeException) {
            ServiceInvokeException exception = (ServiceInvokeException) ex;
            httpStatus = exception.getCode();
            errorMsg = ex.getMessage();
        } else {
            errorMsg = DWZ_CODE_ERROR_MESSAGE;
        }

        if (AjaxUtil.isAjax(request)) {
            response.setHeader("Content-Type", "application/json;charset=UTF-8");
            response.setContentType("application/json;charset=UTF-8");

            String jsonObject = JSONObject.toJSONString(getAjaxResponse(httpStatus, errorMsg, ex.getMessage()));
            PrintWriter out = null;
            try {

                out = response.getWriter();
                out.print(jsonObject);
                out.flush();
            } catch (IOException e) {

                LOGGER.error("{}", e);
            } finally {
                if (out != null) {
                    out.close();
                }
            }
            return null;
        } else {
            request.setAttribute("message", errorMsg);
            request.setAttribute("errorMessage", ex.getMessage());
            // 根据不同错误转向不同页面
            return "error/ime_exception";
        }
    }

    private Object getAjaxResponse(HttpStatus httpStatus, String errorMsg, String detail) {
        if (httpStatus != null) {
            //未登录
            if (HttpStatus.UNAUTHORIZED == httpStatus) {
                return AjaxUtil.ajaxTimeout(errorMsg);
            }
        }
        return AjaxUtil.ajaxError(errorMsg, detail);
    }

    /**
     * 获取转发url
     * @param request
     * @return
     */
    public String getForwardUrl(HttpServletRequest request) {
        String requestUrl = request.getServletPath();
        String[] url = requestUrl.split("/");
        String forwardUrl = "";
        if (url.length > 1) {
            forwardUrl = request.getContextPath() + "/" + url[1];
        }
        return forwardUrl;
    }

    private String getManagementExceptionMessage(Exception ex) {
        ServiceInvokeException exception = (ServiceInvokeException) ex;
        return exception.getMessage();
    }

    public DWZResult getDWZJsonObject(DwzStatusCode statusCode, String message, String navTabId, String rel,
            DwzCallbackType callbackType, String forwardUrl, String confirmMsg, Object data) {
        DWZResult dwzResult = null;

        // 回调状态
        if (null == statusCode) {
            LOGGER.error("Dwz 的状态码statusCode为null，异常状态。");
            return null;
        }
        // 回调状态
        if (null == callbackType) {
            callbackType = DwzCallbackType.EMPTY;
        }
        dwzResult = new DWZResult(statusCode.getValue(), message, navTabId, rel, callbackType.getValue(), forwardUrl,
                confirmMsg, data);
        return dwzResult;
    }

    /**
     * navTabAjaxDone
     * 
     * @param navTabId
     * @param rel
     * @param callbackType
     * @param forwardUrl
     * @param confirmMsg
     * @param data
     * @return
     */
    public DWZResult navTabAjaxDone(String navTabId, String rel, DwzCallbackType callbackType, String forwardUrl,
            String confirmMsg, Object data) {
        return navTabAjaxDone(DWZ_CODE_OK_MESSAGE, navTabId, rel, callbackType, forwardUrl, confirmMsg, data);
    }


    public DWZResult navTabAjaxDone(String message, String navTabId, String rel, DwzCallbackType callbackType,
            String forwardUrl, String confirmMsg, Object data) {
        return getDWZJsonObject(DwzStatusCode.OK, message, navTabId, rel, callbackType, forwardUrl, confirmMsg, data);
    }

    public DWZResult dialogAjaxDone(String navTabId, String rel, String forwardUrl, Object data) {
        return dialogAjaxDone(DWZ_CODE_OK_MESSAGE, navTabId, rel, forwardUrl, data);
    }


    public DWZResult dialogAjaxDone(String message, String navTabId, String rel, String forwardUrl, Object data) {
        return getDWZJsonObject(DwzStatusCode.OK, message, navTabId, rel, DwzCallbackType.CLOSECURRENT, forwardUrl,
                null, data);
    }

    public DWZResult ajaxDone(Object data) {
        return ajaxDone(DWZ_CODE_OK_MESSAGE, data);
    }


    public DWZResult ajaxDone(String message, Object data) {
        return getDWZJsonObject(DwzStatusCode.OK, message, null, null, DwzCallbackType.EMPTY, null, null, data);
    }


    public DWZResult ajaxError(String message) {
        return getDWZJsonObject(DwzStatusCode.ERROR, message, null, null, DwzCallbackType.EMPTY, null, null, null);
    }


    public DWZResult ajaxTimeout(String message) {
        return getDWZJsonObject(DwzStatusCode.TIMEOUT, message, null, null, DwzCallbackType.EMPTY, null, null, null);
    }


}
